package main

import (
	"fmt"
	"reflect"
)

type Student struct {
	Name string
	Age  int
}

func main() {
	var num int = 100
	//reflectTest01(num)

	stu := Student{
		Name: "Tom",
		Age:  15,
	}
	//reflectTest02(stu)
	fmt.Println(stu)
	fmt.Println(num)
	reflectTest03(&num)
	fmt.Println(num)
}

func reflectTest01(b interface{}) {
	// 请编写一个案例，演示对(基本数据类型、interface{}、reflect.Value)进行反射的基本操作

	// 通过反射获取到传入的变量的type,kind,值
	// 1、先获取到reflect.Type
	rTyp := reflect.TypeOf(b)
	fmt.Println("rType =", rTyp)

	// 2、获取到reflect.Value
	rVal := reflect.ValueOf(b)
	fmt.Println("rVal =", rVal)
	fmt.Println(2 + rVal.Int())

	// 3、将rVal转成interface{}
	iV := rVal.Interface()

	// 4、将interface{}转为需要的类型
	num := iV.(int)
	fmt.Println("num =", num)
}

func reflectTest02(b interface{}) {
	// 请编写一个案例，演示对(结构体类型、interface{}、reflect.Value)进行反射的基本操作

	// 通过反射获取到传入的变量的type,kind,值
	// 1、先获取到reflect.Type
	rTyp := reflect.TypeOf(b)
	fmt.Println("rType =", rTyp)

	// 2、获取到reflect.Value
	rVal := reflect.ValueOf(b)
	fmt.Println("rVal =", rVal)
	fmt.Println("rTyp.Kind =", rTyp.Kind())
	fmt.Println("rVal.Kind =", rVal.Kind())

	// 3、将rVal转成interface{}
	iV := rVal.Interface()

	// 4、将interface{}转为需要的类型
	stu, ok := iV.(Student)
	if ok {
		fmt.Printf("stuName = %s, stuAge = %d", stu.Name, stu.Age)
	}
}

func reflectTest03(b interface{}) {
	// 通过反射，修改
	// num int的值
	rVal := reflect.ValueOf(b)
	rVal.Elem().SetInt(1000)
}
